package com.algorithms;

import com.algorithms.arrays.Array;
import com.algorithms.arrays.NoCountQueue;
import com.algorithms.arrays.Queue;
import com.algorithms.arrays.Stack;
import com.algorithms.sorts.BubbleSort;
import com.algorithms.sorts.InsertionSort;
import com.algorithms.sorts.MergeSort;
import com.algorithms.sorts.SelectionSort;
import com.algorithms.sorts.advances.HeapSort;
import com.algorithms.sorts.advances.QuickSort;
import com.algorithms.sorts.advances.ShellSort;
import com.algorithms.utils.AlgorithmException;
import com.algorithms.utils.Utils;

public class test extends Thread {
	int[] testArr;
	public void run(){
//		test_arrays();
		test_sorts();	
	}
	
	private void test_arrays(){
		//test1();
		//test1_stack();
		
		//test1_queue();
		test1_nocountqueue();
	}
	
	private void test_sorts(){
		System.out.println("original data:");
		testArr = Utils.genRandomInts(100, 1000);
		for (int i = 0; i < testArr.length; i++){
			System.out.print(testArr[i]);
			if (i < testArr.length - 1){
				System.out.print(", ");
			}else{
				System.out.println();
			}			
		}
		
		test8();
		test7();
		test6();
		test5();
		test4();
		test3();
		test2();

	}
	
	/**
	 * quick sort
	 */
	private void test8(){
		int[] pTest = new int[testArr.length];
		for (int i = 0; i < testArr.length; i++){
			pTest[i] = testArr[i];
		}

		HeapSort ms = new HeapSort(pTest, testArr.length);
		ms.sortWithMeasure();
		ms.printElements();
	}
	
	
	/**
	 * quick sort
	 */
	private void test7(){
		int[] pTest = new int[testArr.length];
		for (int i = 0; i < testArr.length; i++){
			pTest[i] = testArr[i];
		}
		
		QuickSort ms = new QuickSort(pTest, testArr.length);
		ms.sortWithMeasure();
		ms.printElements();
	}
	
	/**
	 * shell sort
	 */
	private void test6(){
		int[] pTest = new int[testArr.length];
		for (int i = 0; i < testArr.length; i++){
			pTest[i] = testArr[i];
		}
		
		ShellSort ms = new ShellSort(pTest, testArr.length);
		ms.sortWithMeasure();
		ms.printElements();
	}
	
	/**
	 * merge sort
	 */
	private void test5(){
		int[] pTest = new int[testArr.length];
		for (int i = 0; i < testArr.length; i++){
			pTest[i] = testArr[i];
		}
		
		MergeSort ms = new MergeSort(pTest, testArr.length);
		ms.sortWithMeasure();
		ms.printElements();
	}
	
	/**
	 * insertion sort
	 */
	private void test4(){
		int[] pTest = new int[testArr.length];
		for (int i = 0; i < testArr.length; i++){
			pTest[i] = testArr[i];
		}
		
		InsertionSort ss = new InsertionSort(pTest, testArr.length);
		ss.sortWithMeasure();
		ss.printElements();
	}
	
	
	/**
	 * selection sort
	 */
	private void test3(){
		int[] pTest = new int[testArr.length];
		for (int i = 0; i < testArr.length; i++){
			pTest[i] = testArr[i];
		}
		
		SelectionSort ss = new SelectionSort(pTest, testArr.length);
		ss.sortWithMeasure();
		ss.printElements();
	}
	
	/**
	 * bubble sort
	 */
	private void test2(){
		int[] pTest = new int[testArr.length];
		for (int i = 0; i < testArr.length; i++){
			pTest[i] = testArr[i];
		}
		
		BubbleSort bs = new BubbleSort(pTest, testArr.length);
		bs.sortWithMeasure();
		bs.printElements();
	}
	
	private void test1_nocountqueue(){
		NoCountQueue<Integer> queue = new NoCountQueue<Integer>(10);
		testArr = Utils.genRandomInts(10, 1000);
		try {
			for (int i = 0; i < testArr.length; i++){
				queue.push(testArr[i]);
				System.out.print(testArr[i] + ",");
			}
			System.out.println();
			
			for (int i=0; i < 8; i++){
				System.out.print(queue.pop() + ",");
			}
			int num1 = queue.pop();
			int num2 = queue.pop();
			
			queue.push(15);
			System.out.println("added 1 more");
			queue.push(52);
			System.out.println("added 2 more");
			queue.push(86);
			System.out.println("added 3 more");
			
			System.out.println("num1: " + num1 + ", num2: " + num2);
		}catch(AlgorithmException e){
			e.printStackTrace();
		}
	}
	
	private void test1_queue(){
		Queue<Integer> queue = new Queue<Integer>(10);
		testArr = Utils.genRandomInts(10, 1000);
		try {
			for (int i = 0; i < testArr.length; i++){
				queue.push(testArr[i]);
				System.out.print(testArr[i] + ",");
			}
			System.out.println();
			
			for (int i=0; i < 7; i++){
				System.out.print(queue.pop() + ",");
			}
			int num1 = queue.pop();
			int num2 = queue.pop();
			
			queue.push(15);
			System.out.println("added 1 more");
			queue.push(52);
			System.out.println("added 2 more");
			queue.push(86);
			System.out.println("added 3 more");
			
			System.out.println("num1: " + num1 + ", num2: " + num2);
		}catch(AlgorithmException e){
			e.printStackTrace();
		}
	}
	
	private void test1_stack(){
		Stack<Integer> stack = new Stack<Integer>(20);
		testArr = Utils.genRandomInts(20, 1000);
		try {
			for (int i = 0; i < testArr.length; i++){
				stack.push(testArr[i]);
			}
			
			int num1 = stack.pop();
			int num2 = stack.pop();
			
			System.out.println("num1: " + num1 + ", num2: " + num2);
		}catch(AlgorithmException e){
			e.printStackTrace();
		}
		
		
	}
	
	private void test1(){
		Array<Integer> arr = new Array<Integer>(100);
		try{
			// step 1
			System.out.println("--------- test 1-1 ---------");
			arr.add(new Integer(5));
			arr.add(new Integer(7));
			arr.add(new Integer(21));
			arr.add(new Integer(46));
			arr.add(new Integer(39));
			arr.add(new Integer(86));
			arr.add(new Integer(75));
			
			arr.printElements();
			
			// step 2
			System.out.println("--------- test 1-2 ---------");
			arr.insert(2, new Integer(69));
			arr.insert(6, new Integer(17));
			arr.insert(7, new Integer(36));
			
			arr.printElements();
			
			// step 3
			System.out.println("--------- test 1-3 ---------");
			arr.remove(5);
			arr.remove(18);
			
			arr.printElements();
			
		}catch(AlgorithmException aEx){
			System.err.println(aEx.getMessage());
		}
	}
	
	public static void main(String args[]){
		new test().start();
	}
}
